package org.zxp.onedoteight.lambda;

import org.apache.commons.collections.ArrayStack;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
 * @program: effectiveJava
 * @description:
 * @author: X-Pacific zhang
 * @create: 2020-03-19 11:35
 **/
public class LambdaTest {
    /**
     * 测试无参数lambda
     */
    @Test
    public void test1() throws InterruptedException {
        new Thread(() -> System.out.println(Thread.currentThread().getName())).start();
        Thread.sleep(50);
        System.out.println(Thread.currentThread().getName());
    }

    /**
     * 测试有参数lambda(省略写法)
     */
    @Test
    public void test2() {
        List<String> list = Arrays.asList("1", "4", "3", "2");
        Collections.sort(list, (a, b) -> a.compareTo(b));
        list.forEach(s -> System.out.println(s));
    }

    /**
     * 测试有参数lambda(详细写法 ，有返回值，多行)
     */
    @Test
    public void test3() {
        List<String> list = Arrays.asList("1", "4", "3", "2");
        Collections.sort(list, (String a, String b) -> {
            return a.compareTo(b);
        });
        list.forEach(s -> System.out.println(s));
    }

    /**
     * 自定义的方式使用lambda表达式
     */
    @Test
    public void test4() {
        System.out.println(invokeOpe(2, 10, (x, y) -> x * y));
    }

    public int invokeOpe(int x, int y, Operate<Integer, Integer> o) {
        return o.ope(x, y);
    }


    /**
     * 通过Function接口（jdk8自带）实现lambda的使用
     */
    @Test
    public void test5() {
        //jdk8提供了一系列的FunctionalInterface来帮助我们快速的实现lambda
        //其实这些接口是各种常见的行为体现，用来方便的定义lambda行为进行传递
        System.out.println(invokeFunction(10, a -> a + 10));
    }

    /**
     * 这个方法主要用来调用func的apply方法，实际工作过程中如果有Function接口的行为直接用Function作为参数传递会更灵活方便
     *
     * @param a
     * @param func
     * @return
     */
    public int invokeFunction(int a, Function<Integer, Integer> func) {
        if (a > 100) {
            return func.apply(a);
        } else {
            return func.apply(a) * 100;
        }
    }

    /**
     * 通过BiFunction来实现双入参
     */
    @Test
    public void test6() {
        int a = 30;
        int b = 2;
        //加
        System.out.println(invokeBiFunction(a,b,(x,y)->x+y));
        //减
        System.out.println(invokeBiFunction(a,b,(x,y)->x-y));
        //乘
        System.out.println(invokeBiFunction(a,b,(x,y)->x*y));
        //除
        System.out.println(invokeBiFunction(a,b,(x,y)->x/y));


    }


    public int invokeBiFunction(int a, int b, BiFunction<Integer, Integer, Integer> func) {
        return func.apply(a,b);
    }


    @Test
    public void test7(){
        List<String> list = Arrays.asList("aaaa","asdasasda","wqeqeqe","asdsfsf","wwww","eeeee");
        filter(list,s -> s.startsWith("a")).forEach(s -> System.out.println(s));
    }

    public List<String> filter(List<String> list, Predicate<String> predicate){
        List<String> result = new ArrayList<>();
        list.forEach(s -> {
            if(predicate.test(s)){
                result.add(s);
            }
        });
        return result;
    }
}
